Using a class for your filter structure

Beginning with VirtualDub 1.4.11, the API supports enough functionality to allow you to use a regular class object for your filter data structure, which greatly simplifies coding if you are willing to forego compatibility with earlier versions of VirtualDub, or forks thereof. Doing this requires a minimum of API V8 (1.4.11) and a bit of C++ hackery.


Requiring API V8 will lock your filter out from some versions of Avisynth, which is unnecessary since Avisynth does not have a GUI configuration dialog and thus does not clone filter configuration structures in the fashion that necessitates a copy constructor. You may want to detect Avisynth in your filter startup and avoid failing on API version in that case.

How it is done

The three critical functions needed here are initProc, copyProc, and deinitProc. They are used as follows:

Because VirtualDub allocates the filter structure, and not the filter itself, setting this up requires a bit of C++ magic. For initProc, you need the language feature called placement new:

#include <new>

struct MyFilterData;

int __cdecl myInitProc(FilterActivation *fa, const FilterFunctions *ff) {
    new(fa->filter_data) MyFilterData;
    return 0;
}

copyProc is implemented almost the same way:

void __cdecl myCopyProc(FilterActivation *fa, const FilterFunctions *ff, void *dst) {
    new(dst) MyFilterData((MyFilterData *)fa->filter_data);
}

Finally, deinitProc manually invokes the destructor:

void __cdecl myDeinitProc(FilterActivation *fa, const FilterFunctions *ff, void *dst) {
    ((MyFilterData *)fa->filter_data)->~MyFilterData();
}

That's it. Now you can use heap pointers, class objects with non-trivial destructors, and virtual method functions without issues.

[up] back to main page


VirtualDub external filter SDK 1.05©1999-2001 Avery Lee <phaeron@virtualdub.org>